home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-25 | 13.9 KB | 558 lines | [TEXT/PJMM] |
- { ******************************************************** }
- { "wBMWindSubs.p" }
- { }
- { by John A. Love, III [ Washington Apple Pi Users' Group] }
- { }
- { using Symantec's "THINK Lightspeed Pascal", v 3.02 }
- { }
- { ******************************************************** }
-
-
- UNIT wBMWindSubs;
-
- INTERFACE
-
- USES
- Quickdraw, Palettes, wBMInterface, wBMGlobals, wBMMiscSubs, wBMScrollSubs, wBarMenuProc, wBMBalloons;
-
-
- FUNCTION InitWindowStorage: allWSHdl;
- PROCEDURE CalcWindowRect (window: WindowPtr; VAR r: Rect);
- PROCEDURE DisplayWindow (window: WindowPtr; TLPR: Point);
- FUNCTION DoNewWindow (windowID, wMBARID: INTEGER; VAR offset: Point): BOOLEAN;
- PROCEDURE CloseOurWindow (window: WindowPtr);
- PROCEDURE DoCloseAll;
- PROCEDURE UncheckOldItem (windMenu: MenuHandle);
- { ----- Thanks to Scott Knaster's "Macintosh Programming Secrets" ----- }
- PROCEDURE AddWindowMenu;
- FUNCTION ItemFromName (theName: Str255): INTEGER;
- PROCEDURE AddWindToMenu (window: WindowPtr);
- PROCEDURE DelWindFromMenu (window: WindowPtr);
-
-
- CONST
- mWindow = 4; { ID of Window MENU. }
- AEWindItem = 1;
- wholeMenu = 0;
-
- VAR
- WindowMenu: MenuHandle;
- windowName: Str255;
- firstWindowItem: INTEGER;
- textH: TEHandle;
-
-
-
-
- IMPLEMENTATION
-
-
-
-
- FUNCTION InitWindowStorage: allWSHdl;
- { Call this hummer after "InitManagers". }
-
- VAR
- wsHdl: allWSHdl;
-
-
- BEGIN
-
- InitWindowStorage := NIL; { Worry-wart !! }
- wsHdl := allWSHdl(NewClearHandle(SizeOf(allWStorage)));
- IF MemError = noErr THEN
- BEGIN
- MoveHHi(Handle(wsHdl));
- HLock(Handle(wsHdl));
- ;
- windowCount := 0;
- newCount := 0;
- InitWindowStorage := wsHdl;
- END; { IF noErr }
-
- END; { InitWindowStorage }
-
-
-
- { --------------------------------------------------------- }
- { CanNOT use the "structRgn" field of the window since this }
- { region handle will be NIL if the window is NOT visible. }
- { --------------------------------------------------------- }
-
- PROCEDURE CalcWindowRect (window: WindowPtr; VAR r: Rect);
-
-
- BEGIN
-
- windType := GetWindowType(window); { In DoActivate, also. }
-
- r := window^.portRect;
- InsetRect(r, -frame, -frame); { Include frame. }
- IF (windType = 0) OR (windType > 3) THEN
- r.top := r.top - title; { Window has a title bar. }
- IF (windType = documentProc) OR (windType = altDBoxProc) OR (windType = noGrowDocProc) OR (windType = zoomDocProc) THEN
- BEGIN
- r.bottom := r.bottom + shadow;
- r.right := r.right + shadow;
- END; { Window has a shadow frame. }
-
- END; { CalcWindowRect }
-
-
-
- { --------------------------------------------------- }
- { Before showing the window, center it on the screen. }
- { --------------------------------------------------- }
-
- FUNCTION GetTLWindPortRect (window: WindowPtr; oldOffset: Point): Point;
- { newOffset := GetTLWindPortRect(TheWindow, oldOffset); }
-
- VAR
- wFrameRect: Rect;
- temp: INTEGER;
- PR: Point;
-
- BEGIN
-
- moreNew := TRUE; { Assume we can !! }
-
- CalcWindowRect(window, wFrameRect); { Calls GetWindowType. }
-
- WITH screenBits.bounds DO { ... so it doesn't overlap 2nd screen. }
- temp := bottom - top;
- WITH wFrameRect DO
- temp := temp - (bottom - top); { screen height - window height }
- temp := temp - mBarHt;
- IF temp < 0 THEN
- temp := 0;
- temp := temp DIV 2;
- temp := temp + frame;
- IF (windType = 0) OR (windType > 3) THEN
- temp := temp + title; { Window has a title bar. }
- WITH PR, screenBits.bounds DO
- BEGIN
- IF oldOffset.v <> 0 THEN
- v := oldOffset.v + deltaOffset.v { From where we were ... }
- ELSE
- v := top + temp; { ... or from scratch. }
- IF v > (bottom - 2 * deltaOffset.v) THEN
- moreNew := FALSE;
- END; { WITH PR, screenBits.bounds }
- { ----- }
- WITH screenBits.bounds DO
- temp := right - left;
- WITH wFrameRect DO
- temp := temp - (right - left); { screen width - window width }
- IF temp < 0 THEN
- temp := 0;
- WITH PR, screenBits.bounds DO
- BEGIN
- IF oldOffset.h <> 0 THEN
- h := oldOffset.h + deltaOffset.h
- ELSE
- h := left + temp DIV 2 + frame;
- IF h > (right - 2 * deltaOffset.h) THEN
- moreNew := FALSE;
- END; { WITH PR, screenBits.bounds }
-
- GetTLWindPortRect := PR;
-
- END; { GetTLWindPortRect }
-
-
-
- PROCEDURE DisplayWindow (window: WindowPtr; TLPR: Point);
-
-
- BEGIN
-
- { The change of TLPR to Global coordinates implemented below is }
- { localized to TLPR passed above since TLPR is not VARed within }
- { "DisplayWindow". NOTE also that _LocalToGlobal will NOT work }
- { here because "GetTLWindPortRect" returns TLPR in local SCREEN }
- { coordinates and the current port = my window … thus, we'd be }
- { mixing apples & oranges so-to-speak. }
-
- SubPt(screenBits.bounds.topLeft, TLPR);
- ;
- MoveWindow(window, TLPR.h, TLPR.v, TRUE);
- ShowHide(window, TRUE);
-
- END; { DisplayWindow }
-
-
-
- FUNCTION DoNewWindow (windowID, wMBARID: INTEGER; VAR offset: Point): BOOLEAN;
- { IF NOT DoNewWindow( ) THEN }
- { OhOh; }
-
- VAR
- i: INTEGER;
- destR, viewR: Rect;
-
- FUNCTION FindWStorage (VAR index: INTEGER): BOOLEAN;
-
- BEGIN
- index := 1;
- WITH windowStorage^^ DO
- BEGIN
- WHILE (index <= maxWindows) & ones[index].inUse DO
- index := index + 1;
- ;
- IF index <= maxWindows THEN { Found one NOT in use. }
- BEGIN
- ones[index].inUse := TRUE;
- FindWStorage := TRUE;
- END
- ELSE { no more windows allowed }
- FindWStorage := FALSE;
- END; { WITH }
- END; { FindWStorage }
-
-
- PROCEDURE SetWindowTitle (window: WindowPtr);
-
- CONST
- titlePrefix = 'Untitled -';
-
- VAR
- numString: Str255;
-
- BEGIN
-
- NumToString(newCount, numString);
- SetWTitle(window, concat(titlePrefix, numString));
-
- END; { SetWindowTitle }
-
-
- BEGIN { DoNewWindow }
-
- DoNewWindow := FALSE;
- moreNew := moreNew & FindWStorage(i); { i is VARed. }
- IF NOT moreNew THEN
- EXIT(DoNewWindow);
-
- IF aMac2 THEN
- TheWindow := GetNewCWindow(windowID, @windowStorage^^.ones[i].ws, WindowPtr(-1))
- ELSE
- TheWindow := GetNewWindow(windowID, @windowStorage^^.ones[i].ws, WindowPtr(-1));
- ;
- IF TheWindow = NIL THEN
- BEGIN
- windowStorage^^.ones[i].inUse := FALSE; { Reverse effect of FindWStorage. }
- EXIT(DoNewWindow);
- END;
- ;
- SetPort(TheWindow);
-
- mBar := wGetNewMBar(TheWindow, wMBARID);
- IF mBar <> NIL THEN
- wAddWMB(mBar);
-
- IF windowID = newWindowID THEN
- BEGIN
- newCount := newCount + 1;
- SetWindowTitle(TheWindow);
- ourControl := GetNewControl(horizScrollID, TheWindow);
- ourControl := GetNewControl(vertScrollID, TheWindow);
- ;
- WITH TheWindow^.portRect DO
- SetRect(viewR, 0, 0, right - (scrollWidth - 1), bottom - (scrollHeight - 1));
- IF mBar <> NIL THEN
- viewR.top := viewR.top + mBarHt;
- destR := viewR;
- InsetRect(destR, 4, 4);
- ;
- textH := TENew(destR, viewR);
- SetWRefCon(TheWindow, LONGINT(textH));
- END { newWindowID }
- ELSE
- SetWRefCon(TheWindow, 0); { rDocProc }
-
- offset := GetTLWindPortRect(TheWindow, offset); { oldOffset --> newOffset }
-
- ScrollResize(TheWindow); { Does nada if NO Scroll Bars. }
- DisplayWindow(TheWindow, offset);
-
- { Since an Update Event draws the MSAs & the Window Menu Bar, }
- { we do NOT want these drawn by the DoActivate PROC: }
- brandNew := TRUE;
-
- windowCount := windowCount + 1;
- moreNew := moreNew & (windowCount < maxWindows);
- DoNewWindow := TRUE;
- ;
- AddWindToMenu(TheWindow);
-
- END; { DoNewWindow }
-
-
-
- { ----------------------- }
- { One at a time, folks !! }
- { ----------------------- }
-
- PROCEDURE CloseOurWindow (window: WindowPtr);
-
- VAR
- myPic: PicHandle;
- pal: PaletteHandle;
- aux: BOOLEAN;
- auxWind: AuxWinHndl;
-
- PROCEDURE DisposeWStorage (wp: WindowPtr);
-
- VAR
- i: INTEGER;
- found: BOOLEAN;
- wsHState: SignedByte;
-
- BEGIN
-
- found := FALSE;
-
- { On input to this PROC, the windowStorage Handle is locked. }
- { "IF wp = @ones[i].ws" below creates a Pointer to a field }
- { in this locked Master Pointer. Therefore, the former is }
- { also locked, with Bit #31 set. But the passed WindowPtr }
- { is NOT locked and, therefore, its Bit #31 is clear. So ... }
- { }
- { oneWStorage dsec 0 }
- { inUse byte ; = 0 }
- { fill byte ; = 1 }
- { ws byte WindowSize ; = 2 }
- { dend }
- { ... }
- { move.l windowStorage,a0 }
- { move.l (a0),a4 ; Locked Master Pointer. }
- { lea ws(a4),a1 ; Bit #31 also set. }
- { cmpa.l wp,a1 ; wp = 8(a6) }
- { ... }
-
- wsHState := HGetState(Handle(windowStorage));
- windowStorage^ := allWSPtr(QuickStrip(Ptr(windowStorage^)));
- WITH windowStorage^^ DO
- BEGIN
- FOR i := 1 TO maxWindows DO
- IF ones[i].inUse THEN
- IF wp = @ones[i].ws THEN
- BEGIN
- found := TRUE;
- Leave;
- END;
- IF found THEN
- ones[i].inUse := FALSE { Undo effect of FindWStorage. }
- ELSE { should NOT happen !! }
- ;
- END; { WITH }
- ;
- { We have NOT done anything to move memory, }
- { therefore _MoveHHi is NOT required. }
- HSetState(Handle(windowStorage), wsHState);
-
- END; { DisposeWStorage }
-
-
- BEGIN { CloseOurWindow }
-
- IF window = NIL THEN
- EXIT(CloseOurWindow);
-
- IF WindowPeek(window)^.windowKind < 0 THEN
- CloseDeskAcc(WindowPeek(window)^.windowKind)
- ELSE
- BEGIN
- IF aMac2 THEN
- BEGIN
- pal := GetPalette(window);
- IF pal <> NIL THEN
- DisposePalette(pal);
- END; { IF aMac2 }
-
- myPic := GetWindowPic(window);
- IF myPic <> NIL THEN
- BEGIN
- HUnlock(Handle(myPic));
- ReleaseResource(Handle(myPic));
- END; { IF myPic <> NIL }
-
- textH := TEHandle(GetWRefCon(window));
- IF textH <> NIL THEN
- TEDispose(textH);
-
- wDeleteWMB(window);
- DelWindFromMenu(window);
- DisposeWStorage(window);
- CloseWindow(window);
-
- WITH offset DO
- BEGIN
- h := h - deltaOffset.h;
- IF h < 0 THEN
- h := 0;
- v := v - deltaOffset.v;
- IF v < 0 THEN
- v := 0;
- END; { WITH }
-
- windowCount := windowCount - 1;
- IF windowCount = 0 THEN
- BEGIN
- { In case a lingering DA doesn't properly handle its "doCursor" routine: }
- InitCursor;
- { Wait till last is gone because all windows share a common Color Table. }
- IF aMac2 THEN
- BEGIN
- aux := GetAuxWin(window, auxWind);
- IF aux THEN
- ReleaseResource(Handle(auxWind));
- END; { IF aMac2 }
- END; { IF no more windows }
-
- moreNew := TRUE;
- END; { NOT a Desk Accessory window }
-
- END; { CloseOurWindow }
-
-
-
- { ----------------------------------------------------------- }
- { DoCloseAll is called from within "DoQuit". Note that we }
- { close windows from back to front by calling CloseBehind }
- { recursively. In this manner, window updating is minimized. }
- { Reference: APDA's "Programmer's Guide to MultiFinder" [B-5] }
- { ----------------------------------------------------------- }
-
- PROCEDURE DoCloseAll;
-
- PROCEDURE CloseBehind (window: WindowPtr);
- BEGIN
- IF window <> NIL THEN
- BEGIN
- CloseBehind(WindowPtr(WindowPeek(window)^.nextWindow));
- CloseOurWindow(window);
- END; { IF }
- END; { CloseBehind }
-
-
- BEGIN
- CloseBehind(FrontWindow);
- END; { DoCloseAll }
-
-
-
- PROCEDURE UncheckOldItem (windMenu: MenuHandle);
-
- VAR
- whichItem: INTEGER;
- markChar: Char;
-
-
- BEGIN
-
- FOR whichItem := firstWindowItem TO CountMItems(windMenu) DO
- BEGIN
- GetItemMark(windMenu, whichItem, markChar);
- IF markChar <> chr(0) THEN
- BEGIN
- CheckItem(windMenu, whichItem, false);
- Leave; { FOR loop }
- END; { IF }
- END; { FOR }
-
- END; { UncheckOldItem }
-
-
-
- PROCEDURE AddWindowMenu;
-
- BEGIN
-
- WindowMenu := NewMenu(mWindow, 'Windows');
-
- IF WindowMenu <> NIL THEN
- BEGIN
- InsertMenu(WindowMenu, 0);
- ;
- IF gInitAppleEvents = noErr THEN
- BEGIN
- AppendMenu(WindowMenu, 'Send “Move Window” AppleEvent<I/M');
- AppendMenu(WindowMenu, '(-');
- firstWindowItem := 5; { After the "Next window" item. }
- END
- ELSE
- firstWindowItem := 3;
- ;
- AppendMenu(WindowMenu, '(Next window/,');
- AppendMenu(WindowMenu, '(-');
- END; { WindowMenu <> NIL }
-
- END; { AddWindowMenu }
-
-
-
- FUNCTION ItemFromName (theName: Str255): INTEGER;
-
- VAR
- itemString: Str255;
- whichItem: INTEGER;
-
-
- BEGIN
-
- FOR whichItem := firstWindowItem TO CountMItems(WindowMenu) DO
- BEGIN
- GetItem(WindowMenu, whichItem, itemString);
- IF itemString = theName THEN
- Leave; { FOR loop }
- END;
-
- ItemFromName := whichItem; { = CountMItems() +1 if NOT found. }
-
- END; { ItemFromName }
-
-
-
- PROCEDURE AddWindToMenu (window: WindowPtr);
-
- VAR
- item: INTEGER;
-
-
- BEGIN
-
- item := CountMItems(WindowMenu);
- UncheckOldItem(WindowMenu); { Un-check the old one ... }
- GetWTitle(window, windowName);
- InsMenuItem(WindowMenu, windowName, item);
- CheckItem(WindowMenu, item + 1, true); { & check the new one. }
-
- END; { AddWindToMenu }
-
-
-
- PROCEDURE DelWindFromMenu (window: WindowPtr);
-
- VAR
- itemString, wpTitle: Str255;
- wPeek: WindowPeek;
-
-
- BEGIN
-
- GetWTitle(window, windowName);
- DelMenuItem(WindowMenu, ItemFromName(windowName));
- wPeek := WindowPeek(FrontWindow)^.nextWindow;
- IF (wPeek <> NIL) & (wPeek^.windowKind = userKind) THEN
- BEGIN
- wpTitle := wPeek^.titleHandle^^;
- CheckItem(WindowMenu, ItemFromName(wpTitle), true); { Check the one in back. }
- END;
-
- END; { DelWindFromMenu }
-
-
-
-
- END. { UNIT = wBMWindSubs }